home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 050 / madtrb17.arc / TREK_PLY.P < prev    next >
Text File  |  1985-09-08  |  32KB  |  1,195 lines

  1. (*
  2. ::::::::::
  3. TRK.PLAY.TEXT
  4. ::::::::::
  5. *)
  6. (* overlay *) procedure playgame(var gstat: integer);
  7. label 10;
  8.  
  9.   function findit(fromx,fromy,tox,toy:integer):real;
  10.   var
  11.      enemy:real;
  12.   begin
  13.      if babble then findit:= rand(0,119) /10
  14.      else
  15.     if tox=fromx then
  16.        if toy-fromy>0 then findit:= 0
  17.        else findit:= 6
  18.     else begin
  19.        enemy:= arctan((toy-fromy)/(tox-fromx))/pi*180;
  20.        if enemy-90<0 then enemy:= enemy+360;
  21.        enemy:= (enemy-90)/30;
  22.        if abs(tox-fromx) div (tox-fromx)=-1 then findit:= 18 - enemy
  23.        else findit:= 12 - enemy
  24.       end
  25.   end;
  26.  
  27.   function hit(distance:real; var xco,yco: integer;
  28.                    fromx, fromy:integer):boolean;
  29.   begin
  30.     hit:=false;
  31.     xco:=fromx+round(distance*cos((90-30*direction)*pi/180));
  32.     yco:=fromy+round(distance*sin((90-30*direction)*pi/180));
  33.     if ok(xco,yco) then
  34.       if (universe[xco,yco].ch <> ' ') and not((xco=fromx) and (yco=fromy)) then
  35.     hit:=true
  36.   end;
  37.   
  38.   function out(which : system):boolean;
  39.   begin
  40.     out:= systems[which] < opefficiency
  41.   end;
  42.   
  43.   procedure writenum(towrite,leng,x,y:integer);
  44.   var
  45.      i: integer;
  46.     s : packed array[0..9] of char;
  47.   begin
  48.       for i:= 1 to leng do begin
  49.       if towrite = 0 then 
  50.           if i = 1 then
  51.           s[leng - i] := '0'
  52.           else
  53.           s[leng - i] := ' '
  54.       else
  55.           s[leng - i] := chr(48 + towrite mod 10);
  56.       towrite:= towrite div 10
  57.       end;
  58.       gotoxy(x+1,y+1);
  59.       for i := 0 to leng - 1 do write(s[i]);
  60.   end;
  61.   
  62.   procedure writestr(x,y : integer; str : string80);
  63.   begin
  64.     gotoxy(x+1,y+1); write(str)
  65.   end;
  66.  
  67.   procedure updateboard;
  68.   var
  69.      j:  system;
  70.      i,x,y: integer;
  71.      red: boolean;
  72.   begin
  73.      if condition <>'docked' then
  74.     begin
  75.     condition:= 'green ';
  76.     for j:= computer to impulse do
  77.      if systems[j] < 75 then condition:= 'yellow';
  78.     condcheck(currx,curry,red);
  79.     if red then condition:= 'red   '
  80.     end;
  81.      if not out(computer) and not out(shortscan) then short(currx,curry);
  82.      numstr(currx,3,0); writestr(54,12,str);
  83.      numstr(curry,3,0); writestr(59,12,str);
  84.      writenum(shields,5,71,6);
  85.      writenum(totalpower-shields,5,71,7);
  86.      writenum(nmbrkling,2,74,8);
  87.      writenum(nmbrbases,2,74,9);
  88.      writenum(nmbrtorps,2,74,10);
  89.      writenum(level,3,47,12);
  90.      writenum(points,5,57,13);
  91.      numstr(stardate,6,1); writestr(70,12,str);
  92.      numstr(deadline,6,1); writestr(70,13,str);
  93.      writestr(70,14,condition)
  94.   end;
  95.  
  96.   procedure finishup(knownstate: boolean);
  97.   begin
  98.     updateboard;
  99.     addscroll('------------ End ------------');
  100.     if not knownstate then
  101.       if shields < 0 then
  102.     begin
  103.       clearscroll;
  104.       addscroll('You have been destroyed. Some');
  105.       addscroll('commander you are!  Your crew');
  106.       addscroll('probably would have mutinied');
  107.       addscroll('anyway.');
  108.       gstat := 0
  109.     end
  110.       else if stardate >= deadline then
  111.     begin
  112.       clearscroll;
  113.       addscroll('You have run out of time.  The');
  114.       addscroll('Organians have intervened in your');
  115.       addscroll('behalf when they saw what a blundering');
  116.       addscroll('excuse for a commander you were.');
  117.       gstat := 2
  118.     end
  119.       else gstat := 4;
  120.     delay(500);
  121.     scroll;
  122.     addscroll('Lt. Uhura reports:');
  123.     scroll;
  124.     addscroll('Message from starfleet runs as follows:');
  125.     scroll;
  126.     if not baseattacked then begin
  127.     addscroll('Your new position n Starfleet,');
  128.     addscroll(' effective immediately:  ');
  129.     scroll;
  130.     if points>8000 then addscroll('      SUPREME COMMANDER')
  131.     else if points>6000 then addscroll('     ADMIRAL')
  132.     else if points>5000 then addscroll('     COMMODORE')
  133.     else if points>4000 then addscroll('    COMMANDER')
  134.     else if points>3000 then addscroll('   LIEUTENANT COMMANDER')
  135.     else if points>2000 then addscroll('   STEWARD')
  136.     else if points>1000 then addscroll('   ENSIGN')
  137.     else addscroll('     SPACE GARBAGE');
  138.     end
  139.     else begin
  140.     addscroll('We told you so...');
  141.     addscroll('   crime does not pay!');
  142.     end;
  143.     delay(6000);
  144.     alldone := true;
  145.   end;
  146.  
  147.   procedure doquestion(questx,questy : integer; encounter : attack); forward;
  148.    { enemy attack and getcommand are mutually recursive with this }
  149.  
  150.   procedure enemyattack(whattodo: what);
  151.   const
  152.      maxobj = 20;
  153.   type
  154.      obj_range =  0..maxobj;
  155.   var
  156.      tempkling,tempbase:  obj_range;
  157.      klingloc,baseloc:  array [obj_range,1..2] of integer;
  158.      shot,klingx,klingy,basex,basey:  integer;
  159.      unknown: boolean;
  160.  
  161.      procedure shieldchek;
  162.      var
  163.     i: integer;
  164.     swarn, rwarn: packed array[0..9] of char;
  165.      begin
  166.     swarn := 'SHIELDS LO';
  167.     rwarn := 'RESERVE LO';
  168.     if totalpower - shields < 0 then shields:= totalpower;
  169.     if shields < 0 then
  170.         finishup(false)
  171.     else
  172.          for i:= 1 to 10 do 
  173.            begin
  174.          gotoxy(43,22);
  175.          if shields < 200 then write(swarn)
  176.          else write('          ');
  177.          gotoxy(43,23);
  178.          if totalpower - shields < 200 then write(rwarn)
  179.          else write('          ');
  180.            end;
  181.      end;
  182.  
  183.      procedure klingmove(fromx,fromy:  integer);
  184.      var
  185.     distance,x,y:  integer;
  186.      begin
  187.     direction:= findit(fromx,fromy,currx,curry);
  188.     if (universe[fromx,fromy].strength < 100) or (nmbrkling < 5) then
  189.        if direction >6 then direction:= direction - 6
  190.        else direction:= direction + 6;
  191.     if sqrt(sqr(fromx-currx)+sqr(fromy-curry))< level + 3 then
  192.        distance:= trunc(sqrt(sqr(fromx-currx)+sqr(fromy-curry)))
  193.     else distance:= level + 3;
  194.     if hit(rand(2,distance),x,y,fromx,fromy) then moveround(x,y);
  195.     if ok(x,y) then
  196.        begin
  197.        universe[x,y]:= universe[fromx,fromy];
  198.        if not ((x=fromx) and (y=fromy)) then
  199.           with universe[fromx,fromy] do
  200.          begin
  201.          strength:= 0;
  202.          ch:= ' '
  203.          end
  204.        end
  205.      end;
  206.  
  207.      procedure shoot(fromx,fromy:  integer);
  208.      label 10;
  209.      begin
  210.     with universe[fromx,fromy] do begin
  211.        if whattodo = pass then shot:= rand(0,2500)
  212.        else shot:= round(1/(sqr(currx-fromx)+sqr(curry-fromy))*
  213.         rand(0,strength));
  214.        if allshields < 0 then
  215.           begin
  216.           shields:=shields-shot;
  217.           totalpower:= totalpower-shot
  218.           end;
  219.        if shot> 0 then
  220.           begin
  221.           scroll;
  222.           numstr(shot,4,0);
  223.           addln(str);
  224.           addln(' unit hit by');
  225.           if whattodo = pass then
  226.          begin
  227.          addscroll(' unknown means');
  228.          shieldchek;
  229.          partdone := true;
  230.          goto 10;
  231.          end
  232.           else case ch of
  233.          '+': addscroll(' Klingon');
  234.          'X': addscroll(' Klingon base');
  235.          'H': addscroll(' Hydran');
  236.          'T': addscroll(' Tholian');
  237.          'R': addscroll(' Romulan');
  238.          'A': addscroll(' Argelian');
  239.          '#','B': addscroll(' starbase')
  240.          end;
  241.           scroll
  242.           end
  243.        end;
  244.   10: end;
  245.  
  246.  
  247.  
  248.      procedure anyshoot(fromx,fromy,tox,toy: integer);
  249.      begin
  250.     shot:= rand(0,500+level*100) div (sqr(fromx-tox) + sqr(fromy-toy));
  251.     if universe[tox,toy].strength < shot then
  252.        with universe[tox,toy] do
  253.           begin
  254.           case ch of
  255.          'A':  addscroll('***Argelian shape-changer destroyed***');
  256.          'T':  addscroll('***Tholian destroyed***');
  257.          'R':  addscroll('***Romulan destroyed***');
  258.          '+':  begin
  259.                nmbrkling:= nmbrkling - 1;
  260.                addscroll('***Klingon destroyed***')
  261.                end;
  262.          'X':  addscroll('***Klingon base destroyed***');
  263.          '#':  begin
  264.                addscroll('***Starbase destroyed***');
  265.                nmbrbases:= nmbrbases - 1;
  266.                if condition = 'docked' then
  267.               begin
  268.               condition:= 'red   ';
  269.               shields:= maxpower;
  270.               totalpower:= maxpower;
  271.               clrmesg;
  272.               mesg(2,'  Lt. Sulu reports:');
  273.               mesg(4,' ENTERPRISE undocked');
  274.               mesg(5,'    and in battle');
  275.               delay(2000)
  276.               end
  277.                end ;
  278.          end;
  279.           ch:= ' ';
  280.           strength:= 0;
  281.           printch(50+tox-currx,5-toy+curry,' ');
  282.           end
  283.     else universe[tox,toy].strength:= universe[tox,toy].strength - shot;
  284.      end;
  285.  
  286.      procedure scan_it;
  287.      var
  288.     i,x,y:  integer;
  289.      begin
  290.     partdone := false;
  291.     tempkling:=0;
  292.     tempbase:=0;
  293.     for x:= currx - 10 to currx + 10 do
  294.        for y:= curry - 5 to curry + 5 do
  295.          if ok(x,y) then
  296.          case universe[x,y].ch of
  297.             'H','O','R','A','T','X','+':  begin
  298.               tempkling:= tempkling + 1;
  299.               klingloc[tempkling,1]:= x;
  300.               klingloc[tempkling,2]:= y;
  301.               if universe[x,y].ch = 'O' then if (currlst >= 'a')
  302.                  and (rand(0,2) = 1) then
  303.                  begin
  304.                 for i:= rand(0,ord(currlst) - ord('a')) to 
  305.                    ord(currlst) - ord('a') - 1 do 
  306.                   list[chr(i + ord('a'))]:= list[chr(i + 
  307.                    ord('b'))];
  308.                 currlst:= pred(currlst)
  309.                  end
  310.               end;
  311.             'B','#':  begin
  312.               tempbase:= tempbase + 1;
  313.              baseloc[tempbase,1]:= x;
  314.               baseloc[tempbase,2]:= y
  315.               end;
  316.             '.':  if allshields < 0 then
  317.                  begin
  318.                  totalpower:= totalpower - trunc(300 * 1 /
  319.                  (sqr(x-currx)+sqr(y-curry)));
  320.                  shields:= shields - trunc(300 * 1 / (sqr(x-currx)+
  321.                 sqr(y-curry)))
  322.                  end;
  323.             '?':  begin doquestion(x,y,chanced); partdone := true end
  324.            end
  325.      end;
  326.  
  327.      procedure fire_it;
  328.      label 10;
  329.      var
  330.     i,j:  obj_range;
  331.      begin
  332.     partdone := false;
  333.     if whattodo = pass then shoot(currx - 1, curry);
  334.     for i:= 1 to tempkling do
  335.        begin
  336.        klingx:= klingloc[i,1];
  337.        klingy:= klingloc[i,2];
  338.        for j:= 1 to tempbase do
  339.           begin
  340.           basex:= baseloc[j,1];
  341.           basey:= baseloc[j,2];
  342.           if universe[klingx,klingy].ch in ['X','+','R','A','T','H'] then
  343.          anyshoot(klingx,klingy,basex,basey);
  344.           if (universe[klingx,klingy].ch in ['X','+','R','A','T']) and
  345.          (universe[basex,basey].ch in ['#','B']) then
  346.          anyshoot(basex,basey,klingx,klingy);
  347.           end
  348.        end;
  349.     for i:= 1 to tempkling do
  350.        if universe[klingloc[i,1],klingloc[i,2]].ch <> ' ' then
  351.           begin
  352.           if (condition <> 'docked') and (universe[klingloc[i,1],klingloc
  353.          [i,2]].ch <> 'O') then
  354.          begin
  355.          shoot(klingloc[i,1],klingloc[i,2]);
  356.          if partdone then goto 10;
  357.          disable(shot)
  358.          end;
  359.          with universe[klingloc[i,1],klingloc[i,2]] do
  360.           if not (ch in ['X','A','T','H','O']) and not((ch = '+') and
  361.           (nomove > -1)) then
  362.         klingmove(klingloc[i,1],klingloc[i,2])
  363.           end;
  364.     if baseattacked then for i:= 1 to tempbase do
  365.        begin
  366.        shoot(baseloc[i,1],baseloc[i,2]);
  367.        if partdone then goto 10;
  368.        disable(shot)
  369.        end;
  370.     shieldchek;
  371. 10:  end;
  372.  
  373.   begin
  374.     if whattodo = go then
  375.       scan_it;
  376.     if not partdone then
  377.       fire_it;
  378.   end; { enemyattack}
  379.  
  380.   procedure battleinfo;
  381.   var
  382.      x,y: integer;
  383.      onefound:  boolean;
  384.  begin
  385.      onefound:= false;
  386.      for y:=curry+5 downto curry -5 do 
  387.     for x:=currx-10 to currx+10 do 
  388.        begin
  389.        if ok(x,y) then 
  390.           if universe[x,y].ch in ['R','H','T','+','X'] then 
  391.          begin
  392.          onefound:= true;
  393.          case universe[x,y].ch of
  394.             '+':  addln('Klingon warship ');
  395.             'X':  addln('Klingon base ');
  396.             'R':  addln('Romulan ');
  397.             'H':  addln('Hydran ');
  398.             'T':  addln('Tholian ')
  399.             end;
  400.         numstr(findit(currx,curry,x,y),4,1);
  401.          addln(concat('at ',str));
  402.          numstr(sqrt(sqr(x-currx)+sqr(y-curry)),4,1);
  403.          addscroll(concat(' and ',str,' parsecs'));
  404.          numstr(round(universe[x,y].strength / 100) * 100,4,0);
  405.          if universe[x,y].ch <>'H' then
  406.             addscroll(concat('     Enemy shields estimated at ',str))
  407.          end;
  408.        if (y=curry-5) and (x=currx+10) and not onefound then
  409.           begin
  410.           clrmesg;
  411.           mesg(3,'      No klingons');
  412.           mesg(4,' reported in area, sir')
  413.           end
  414.        end;
  415.     scroll
  416.   end;
  417.  
  418.   procedure scanlong;
  419.   var
  420.     temp, temp2, i, j: integer;
  421.   begin
  422.     if not out(longscan) then
  423.        begin
  424.        sector(currx-21,curry+11,j);    writenum(j,4,64,0);
  425.        sector(currx,curry+11,j);    writenum(j,4,69,0);
  426.        sector(currx+21,curry+11,j);    writenum(j,4,74,0);
  427.        sector(currx-21,curry,j);    writenum(j,4,64,2);
  428.        sector(currx,curry,j);        writenum(j,4,69,2);
  429.        sector(currx+21,curry,j);    writenum(j,4,74,2);
  430.        sector(currx-21,curry-11,j);    writenum(j,4,64,4);
  431.        sector(currx,curry-11,j);    writenum(j,4,69,4);
  432.        sector(currx+21,curry-11,j);    writenum(j,4,74,4)
  433.        end
  434.     else begin
  435.        clrmesg;
  436.        mesg(3,'  Longrange scanners');
  437.        mesg(4,'   are out yet, sir')
  438.        end
  439.   end;
  440.  
  441.   procedure moveship(x,y:integer);
  442.   begin
  443.     if ok(currx,curry) then
  444.        begin
  445.        universe[currx,curry].ch:= ' ';
  446.        universe[currx,curry].strength:= 0
  447.        end;
  448.     if ok(x,y) then universe[x,y].ch:='@';
  449.     currx:= x;
  450.     curry:= y
  451.   end;
  452.  
  453.   procedure writestuff(casenum: integer);
  454.   begin
  455.      addscroll('Mr. Spock reports:');
  456.      scroll;
  457.      case casenum of
  458.     1:  begin
  459.         addscroll('     Captain, we appear to have moved');
  460.         addscroll('some distance in an unknown direction.')
  461.         end;
  462.     2:  begin
  463.         addscroll('     Captain, apparently we have been');
  464.         addscroll('thrust into a time warp. We have lost');
  465.         addscroll('valuable time.')
  466.         end;
  467.     3:  begin
  468.         addscroll('     Captain, we have inexplicably lost');
  469.         addscroll('much power. Life support is working ');
  470.         addscroll('yet, however.')
  471.         end;
  472.     4:  begin
  473.         addscroll('     Captain, our entire weapons');
  474.         addscroll('systems is dead.')
  475.         end;
  476.     5:  begin
  477.         addscroll('     Captain, all systems are ');
  478.         addscroll('diminished in capacity to function.');
  479.         addscroll('In other words, something has attacked');
  480.         addscroll('only our systems.')
  481.         end;
  482.     6:  begin
  483.         addscroll('     Captain, we have been hit by an');
  484.         addscroll('incredibly powerful blast.');
  485.         if shields >= 0 then addscroll('We are lucky to have survived.')
  486.         end;
  487.     8:  begin
  488.         addscroll('     Captain, we have apparently gained');
  489.         addscroll('an extraordinary amount of power.')
  490.         end;
  491.     9:  begin
  492.         addscroll('     Captain, we apparently have been');
  493.         addscroll('thrust into a time warp. We have gained');
  494.         addscroll('time.')
  495.         end;
  496.        10:  begin
  497.         addscroll('     Captain, all systems have suddenly');
  498.         addscroll('gone to 100% for no apparent reason.')
  499.         end
  500.      end
  501.   end;
  502.  
  503.   procedure raiseshields;
  504.   begin
  505.      repeat
  506.     clrmesg;
  507.     mesg(3,'   How much power');
  508.     mesg(4,'   to the shields?');
  509.     shields := readint
  510.      until (totalpower>=shields);
  511.      clrmesg
  512.   end;
  513.  
  514.   procedure move;
  515.   var
  516.      speed:  real;
  517.      adjspeed,x,y,i:  integer;
  518.  
  519.      procedure findobject(x,y: integer; var str: string80);
  520.      begin
  521.     case universe[x,y].ch of
  522.        '+': str:= 'Klingon';
  523.        'X': str:= 'Klingon base';
  524.        '@','?': str:= 'unknown object';
  525.        'H': str:= 'Hydran';
  526.        'A': str:= 'Argelian';
  527.        'R': str:= 'Romulan';
  528.        'T': str:= 'Tholan';
  529.        '*': str:= 'star';
  530.        'M': str:= 'alien machine';
  531.        ':': str:= 'set of crystals';
  532.        ',': str:= 'comet';
  533.        '^': str:= 'super bomb';
  534.        'O': str:= 'Orion smuggler';
  535.        '/': str:= 'Staff of Surak';
  536.        ')',']': str:= 'set of shields';
  537.        '.': str:= 'neutron star'
  538.        end
  539.      end;
  540.  
  541.      procedure impulsengine;
  542.      label 10;
  543.      var
  544.     tmp: string80;
  545.      begin
  546.     adjspeed:= round(10*speed);
  547.     if totalpower-shields<adjspeed then
  548.        begin
  549.        clrmesg;
  550.        mesg(2,'Engineer Scott reports:');
  551.        mesg(4,'I dinna have enough for');
  552.        mesg(5,'  impulse power, cap''n');
  553.        delay(3000)
  554.        end
  555.     else begin
  556.        if condition= 'docked' then
  557.           begin
  558.           totalpower:= maxpower;
  559.           shields:= maxpower div 2;
  560.           condition:= 'green '
  561.           end;
  562.        clrmesg;
  563.        mesg(4,'       Heading? ');
  564.        direction := readreal;
  565.        universe[currx,curry].ch:= ' ';
  566.        for i:= 0 to adjspeed do
  567.           if hit(i,x,y,currx,curry) then
  568.         begin
  569.          clrmesg;
  570.          mesg(2,'   Mr. Chekov reports:');
  571.          if (universe[x,y].ch in ['#','B']) and not baseattacked then
  572.             begin
  573.             if universe[x,y].ch ='B' then finishup(true);
  574.             condition:= 'docked';
  575.             xdock:= x;
  576.             ydock:= y;
  577.             moveround(x,y);
  578.             moveship(x,y);
  579.             mesg(4,'     shields lowered');
  580.             mesg(5,'       ship docked');
  581.             delay(3000);
  582.             goto 10;
  583.             end
  584.          else if universe[x,y].ch = '#' then
  585.             begin
  586.             mesg(4,'Keptin, the starbase will');
  587.             mesg(5,'  not allow us to dock!');
  588.             delay(4000);
  589.             end
  590.          else if universe[x,y].ch = '%' then
  591.             begin
  592.             currx:= x;
  593.             curry:=y;
  594.             mesg(4,'   We have entered');
  595.             mesg(5,'   the time portal');
  596.             updateboard;
  597.             clearscroll;
  598.             gstat := -1;
  599.             delay(5000);
  600.             partdone := true;
  601.             goto 10;
  602.             end
  603.          else begin
  604.             findobject(x,y,tmp);
  605.             currx:= x;
  606.             curry:= y;
  607.             mesg(3,'Keptin, we have collided');
  608.             mesg(4,concat('  with a ',tmp));
  609.             mesg(5,'All reporting decks are');
  610.             mesg(6,'     disintegrated');
  611.             delay(3000);
  612.             finishup(false)
  613.             end
  614.          end
  615.           else begin
  616.          if i=adjspeed then moveship(x,y);
  617.          if not out(computer) and not out(shortscan) then
  618.             short(x,y)
  619.          end
  620.        end;
  621.     totalpower:= totalpower - adjspeed;
  622.      10: end;
  623.  
  624.      procedure warpdrive;
  625.      begin
  626.     clrmesg;
  627.     if totalpower-shields < round(sqr(speed)/2) then
  628.        begin
  629.        mesg(2,'Engineer Scott reports:');
  630.        mesg(4,' I need more power if');
  631.        mesg(5,'you want to warp cap''n');
  632.        delay(3000)
  633.        end
  634.     else begin
  635.        mesg(4,'       Heading?');
  636.        direction := readreal;
  637.        if hit(round(sqr(speed)),x,y,currx,curry) then moveround(x,y);
  638.        moveship(x,y)
  639.        end
  640.      end;
  641.  
  642.   begin (* move *)
  643.      repeat
  644.     clrmesg;
  645.     mesg(4,'          Speed? ');
  646.     speed := readreal;
  647.     if (condition = 'docked') and (speed >= 1) then
  648.        begin
  649.        mesg(2,'         Captain');
  650.        mesg(4,' We are docked. We must');
  651.        mesg(5,'  use impulse to leave.');
  652.        delay(3000)
  653.        end
  654.      until (speed >= 0) and ((condition <> 'docked') or
  655.     ((condition = 'docked') and (speed < 1)));
  656.      if speed < 1 then
  657.     if not out(impulse) then impulsengine
  658.     else begin
  659.        clrmesg;
  660.        mesg(2,'Engineering reports:');
  661.        mesg(4,'Impulse engines are');
  662.        mesg(5,' still out, Captain');
  663.        delay(3000)
  664.        end
  665.      else if not out(warp) then
  666.     if speed > 8 then
  667.        begin
  668.        clrmesg;
  669.        mesg(3,'         Sir?');
  670.        mesg(4,'We canna go that fast');
  671.        delay(3000)
  672.        end
  673.     else warpdrive
  674.      else begin
  675.     clrmesg;
  676.     mesg(2,'Engineering reports:');
  677.     mesg(4,'      Warp drive');
  678.     mesg(5,'     is still out');
  679.     delay(3000)
  680.     end
  681.   end;
  682.  
  683.   procedure getcommand; forward;
  684.  
  685.   procedure fire(missilepower,distance,fromx, fromy:integer);
  686.   label 10;
  687.   var
  688.      i,x,y:  integer;
  689.        
  690.      procedure reduce;
  691.      var
  692.     x2,y2:  integer;
  693.      begin
  694.     for y2:=-maxuni to maxuni do
  695.        for x2:= -maxuni to maxuni do
  696.           if universe[x2,y2].ch='+' then universe[x2,y2].strength:=
  697.          universe[x2,y2].strength div 2;
  698.     clearscroll;
  699.     addscroll('Mr. Chekov reports:');
  700.     addscroll('  Keptin, all Klingons have lost 1/2');
  701.     addscroll('       of their power due');
  702.     addscroll('  to our destroying their base!')
  703.      end;
  704.  
  705.      procedure hitit;
  706.  
  707.     procedure donotdestroyed;
  708.     begin
  709.        case universe[x,y].ch of
  710.           '+':  addscroll('Klingon hit but not destroyed');
  711.           'X':  addscroll('Klingon base hit but not destroyed');
  712.           'B','#':  begin
  713.             addscroll('Starbase hit but not destroyed');
  714.             baseattacked:= true
  715.             end;
  716.           'A':  addscroll('Argelian hit but not destroyed');
  717.           'R':  addscroll('Romulan hit but not destroyed');
  718.           'T':  addscroll('Tholian hit but not destroyed');
  719.           'H':  begin
  720.             addscroll('Hydran hit but not destroyed');
  721.             numstr(missilepower,5,0);
  722.             addscroll(concat('   Returning shot of ',str,' units!'));
  723.             if allshields < 0 then
  724.                begin
  725.                shields:= shields - missilepower;
  726.                totalpower:= totalpower - missilepower;
  727.                if shields < 0 then finishup(false)
  728.                end
  729.             end;
  730.           'O':  begin
  731.             addscroll('Orion smuggler hit but not destroyed');
  732.             addscroll('   He''s self-destructing!');
  733.            missilepower:= rand(1000,2000);
  734.             numstr(missilepower,5,0);
  735.          addscroll(concat('   Prepare for blast of ',str,' units!'));
  736.             universe[x,y].ch:= ' ';
  737.             universe[x,y].strength:= 0;
  738.             if allshields < 0 then
  739.                begin
  740.                shields:= shields - missilepower;
  741.                totalpower:= totalpower -missilepower;
  742.                if shields < 0 then finishup(false)
  743.                end
  744.             end;
  745.           '/','M','%',',',':',')',']','.','*':
  746.             addscroll('Shot blocked')
  747.           end;
  748.        scroll;
  749.        if not (universe[x,y].ch in ['H','O']) then
  750.           universe[x,y].strength:= universe[x,y].strength - missilepower
  751.     end;
  752.  
  753.      begin
  754.        if universe[x,y].ch = '?' then
  755.      begin
  756.        doquestion(x,y,fired);
  757.        partdone := true;
  758.      end
  759.        else
  760.     begin
  761.        if universe[x,y].ch in ['B','#'] then
  762.           addscroll('Captain, we''ve just hit a starbase');
  763.        if missilepower > universe[x,y].strength then
  764.           begin
  765.           case universe[x,y].ch of
  766.          ',','R','T','H','+','A':  begin
  767.                case universe[x,y].ch of
  768.              'A':  addln('***Argelian shape-changer');
  769.              'R':  addln('***Romulan');
  770.              'T':  addln('***Tholian');
  771.              'H':  addln('***Hydran');
  772.              '+':  begin
  773.                    addln('***Klingon');
  774.                    nmbrkling:= nmbrkling - 1
  775.                    end;
  776.              ',':  addln('***Comet')
  777.              end;
  778.                addscroll(' destroyed***');
  779.                numstr(ord(universe[x,y].pts),2,0);
  780.                addscroll(concat(str,' points'));
  781.                points:= points + ord(universe[x,y].pts);
  782.                end;
  783.          'X':  begin
  784.                addscroll('***Klingon base destroyed***');
  785.               reduce
  786.                end;
  787.          '#':  begin
  788.                addscroll('***Starbase destroyed***');
  789.                nmbrbases:= nmbrbases - 1;
  790.                baseattacked:= true
  791.                end
  792.          end;
  793.           universe[x,y].ch:= ' ';
  794.           universe[x,y].strength:= 0;
  795.           printch(50+x-currx,5-y+curry,' ');
  796.           end
  797.        else donotdestroyed
  798.      end;
  799.      end;
  800.  
  801.   begin  (* fire *)
  802.     for i:= 1 to distance do
  803.       if hit(i,x,y,fromx,fromy) then 
  804.        begin
  805.       if universe[x,y].ch <> '*' then 
  806.         begin
  807.           numstr(missilepower,4,0);
  808.           while pos(str,'0') <> 0 do str[pos(str,'0')]:= ' ';
  809.          addscroll(concat(str,' unit hit'))
  810.         end;
  811.       hitit;
  812.       goto 10;
  813.     end
  814.       else if i=distance then addscroll('Out of range');
  815.   10:end;
  816.  
  817.   procedure torpedo;
  818.   label 10;
  819.   const
  820.      maxtorps = 4;
  821.   var
  822.      number, i:  integer;
  823.      direct:  array[1..maxtorps] of real;
  824.      prompt: string80;
  825.   begin
  826.      partdone := false;
  827.      if nmbrtorps > 0 then
  828.     if condition<> 'docked' then
  829.       if not out(torpedos) then
  830.           begin
  831.           repeat
  832.          clrmesg;
  833.          mesg(4,'   How many torpedos?');
  834.          number := readint;
  835.          if (number > nmbrtorps) or (number > maxtorps) then
  836.             begin
  837.             mesg(3,'        Captain');
  838.             mesg(4,' we can''t fire that many');
  839.             mesg(5,'        torpedos');
  840.             delay(3000)
  841.             end
  842.           until (number <= nmbrtorps) and (number <= maxtorps);
  843.           prompt:= 'Direction of torpedo #i?';
  844.           for i:= 1 to number do
  845.          begin
  846.          prompt[23]:= chr(48 + i);
  847.          clrmesg;
  848.          mesg(4,prompt);
  849.          direct[i] := readreal;
  850.          end;
  851.           for i:= 1 to number do
  852.          begin
  853.          direction:= direct[i];
  854.          if longer > -1 then fire(1000,10,currx,curry)
  855.          else fire(1000,6,currx,curry);
  856.          if partdone then
  857.             goto 10;
  858.          nmbrtorps:= nmbrtorps - 1;
  859.          scroll
  860.          end
  861.           end
  862.       else begin
  863.           clrmesg;
  864.           mesg(4,'Torpedos not functional')
  865.           end
  866.     else begin
  867.        clrmesg;
  868.        mesg(3,'        Captain');
  869.        mesg(4,' we are not allowed to');
  870.        mesg(5,'   shoot while docked');
  871.        end 
  872.     else begin
  873.        clrmesg;
  874.        mesg(4,'    Still out of torpedos');
  875.        end;
  876. 10:end;
  877.  
  878.  
  879. procedure phaser;
  880. const
  881.      maxshots = 4;
  882. var
  883.      requested, number,i: integer;
  884.      direct:  array[1..maxshots] of real;
  885.      strength:  array [1..maxshots] of integer;
  886.      prompt1,prompt2: string80;
  887.  begin
  888.      if not out(phasers) then
  889.     if condition <> 'docked' then
  890.        begin
  891.        repeat
  892.           repeat
  893.          clrmesg;
  894.          mesg(4,'        How many?');
  895.          number := readint;
  896.          if number > maxshots then 
  897.             begin
  898.             mesg(3,'        Captain');
  899.             mesg(4,' we can''t fire that many');
  900.             delay(3000)
  901.             end
  902.           until (ioresult = 0) and (number <= maxshots) ;
  903.           requested:= 0;
  904.          prompt1:= 'Strength of phaser #i?';
  905.           for i:=1 to number do
  906.          begin
  907.          prompt1[21]:= chr(48 + i);
  908.          clrmesg;
  909.          mesg(4,prompt1);
  910.          strength[i] := readint;
  911.          requested:= requested + strength[i]
  912.          end;
  913.           if requested > totalpower - shields then
  914.          begin
  915.          mesg(2,'Engineer Scott reports:');
  916.          mesg(4,'Cap''n, we only got sae');
  917.          mesg(5,'  much power. I canna ');
  918.          mesg(6,'   gie ye that much.');
  919.          delay(3000)
  920.          end
  921.        until requested <= totalpower - shields;
  922.        prompt2:= 'Direction of phaser #i?';
  923.        for i:= 1 to number do
  924.           begin
  925.           clrmesg;
  926.           prompt2[22]:= chr(48+i);
  927.           mesg(4,prompt2);
  928.           direct[i] := readreal;
  929.           end;
  930.        for i:= 1 to number do
  931.           begin
  932.           direction:= direct[i];
  933.          fire(strength[i],10,currx,curry);
  934.           totalpower:= totalpower-strength[i];
  935.           end
  936.       end
  937.     else begin
  938.        clrmesg;
  939.        mesg(3,'        Captain');
  940.        mesg(4,'  we''re not allowed to');
  941.        mesg(5,'    shoot while docked.')
  942.        end
  943.      else begin
  944.     clrmesg;
  945.     mesg(2,' Weapons Room reports:');
  946.     mesg(4,' Phasers are still out');
  947.     mesg(5,'          sir')
  948.     end
  949.   end;
  950.   
  951.   procedure systemchek;
  952.   var
  953.      i: system;
  954.      line,up:  integer;
  955.   begin
  956.      if condition = 'docked' then 
  957.     begin
  958.     totalpower:= maxpower;
  959.     shields:= universe[xdock,ydock].strength;
  960.     nmbrtorps:= 8
  961.     end;
  962.      for i:= computer to impulse do begin
  963.     if condition = 'docked' then up:= 10
  964.     else up:= rand(0,5);
  965.     if systems[i]+ up <100 then systems[i]:= systems[i]+up
  966.     else systems[i]:= 100;
  967.     if not out(computer) then begin
  968.        line := ord(i) + 13;
  969.        gotoxy(47,line+1);
  970.        if systems[i] < opefficiency then
  971.            begin textcolor(Red + Blink); textbackground(8); end
  972.        else
  973.            begin textcolor(WHITE); textbackground(Black); end;
  974.        writenum(systems[i],3,47,line);
  975.        write('%');
  976.        if systems[i] < opefficiency then
  977.            begin textcolor(WHITE); textbackground(Black); end
  978.      end
  979.        end;
  980.      totalpower:= totalpower+ rand(0,10)
  981.   end;
  982.   
  983.   procedure save;
  984.   var
  985.      fname:string80;
  986.   begin
  987.      gstat := 7;
  988.      clearscroll;
  989.      addln('File to save as?');
  990.      readln(con,fname);
  991.      assign(g,fname);
  992.      rewrite(g);
  993.      blockwrite(g,msginfo[1],37*4);
  994.      close(g);
  995.      alldone := true;
  996.   end;
  997.  
  998.   procedure quit;
  999.   label 10;
  1000.   var
  1001.      s : string[1];
  1002.      answer: char;
  1003.   begin
  1004.      clearscroll;
  1005.      togglecursor;
  1006.      addscroll('Confirm:  you wish to quit?');
  1007.      addscroll('Y:quits, R:restores, S:saves');
  1008.      read(kbd,answer);
  1009.      s := ' ';
  1010.      s[1] := answer;
  1011.      addscroll(s);
  1012.      if answer in ['S','s'] then save
  1013.      else if answer in['R','r'] then
  1014.        begin
  1015.      gstat:= -3;
  1016.      alldone := true;
  1017.      partdone := true;
  1018.      togglecursor;
  1019.      goto 10;
  1020.        end
  1021.      else if answer in ['Y', 'y'] then
  1022.        begin
  1023.      gstat:= 1;
  1024.      finishup(true)
  1025.        end  ;
  1026.   10: end;
  1027.  
  1028.  
  1029.   procedure getcommand;
  1030.   label 10;
  1031.   var
  1032.      command: char;
  1033.      ch: char;
  1034.      accumulate, i, limit: integer;
  1035.      prompt: packed array[0..8] of char;
  1036.      
  1037.   begin
  1038.     if alldone then goto 10;
  1039.     prompt:= 'COMMAND ?';
  1040.     if not out(longscan) then
  1041.     if confuse < 0 then
  1042.         scanlong; (* JOHN PLOCHER *)
  1043.     repeat
  1044.       accumulate:= 0;
  1045.       if level > 7 then limit:= rand(20,points div 300)
  1046.       else limit:= 25;
  1047.       while not keypressed and (accumulate <= limit) do
  1048.     begin
  1049.     if not keypressed then delay(200 * skill);
  1050.     gotoxy(55,15); write(prompt);
  1051.     if not keypressed then delay(200 * skill);
  1052.     accumulate:= accumulate + 1;
  1053.     gotoxy(55,15); write('         ');
  1054.     end;
  1055.       gotoxy(55,15);
  1056.       if not keypressed then begin
  1057.       write('        ');
  1058.       command:= ' '
  1059.       end
  1060.       else begin
  1061.       read(kbd,command);
  1062.       write(command);
  1063.       end;
  1064.       partdone := false;
  1065.       if command = chr(13) then clearscroll
  1066.       else if confuse < 0 then
  1067.     case command of
  1068.        ' '    : clearscroll;
  1069.        'W','w',
  1070.        'G','g',
  1071.        'D','d',
  1072.        'U','u':  begin
  1073.                gstat:= ord(command);
  1074.                partdone := true;
  1075.              end;
  1076.        'I','i':  battleinfo;
  1077.        'T','t':  torpedo;
  1078.        'P','p':  phaser;
  1079.        'S','s':  raiseshields;
  1080.        'M','m':  move;
  1081.        'Q','q':  quit
  1082.     end
  1083.       else
  1084.     begin
  1085.       clrmesg;
  1086.       mesg(3,'         What?');
  1087.     end;
  1088.     until partdone or
  1089.       (command in ['Q','q',' ','M','m','T','t','P','p','S','s']);
  1090.   10:end {getcommand};
  1091.  
  1092.   procedure doquestion {questx,questy : integer; encounter : attack};
  1093.   var
  1094.      idx,jdx,j, result: integer;
  1095.      i: system;
  1096.      cmd : packed array[0..3] of char;
  1097.   begin
  1098.      if encounter = fired then result:= rand(1,7)
  1099.      else result:= rand(1,10);
  1100.      universe[questx,questy].ch:= ' ';
  1101.      printch(50+questx-currx,5+curry-questy,' ');
  1102.      clearscroll;
  1103.      for jdx := 1 to 100 do begin
  1104.      sound(rand(100,5000));
  1105.      delay(rand(50,200));
  1106.      nosound;
  1107.      end;
  1108.      case result of
  1109.     1:  begin
  1110.         currx:= currx + rand(-200, 200);
  1111.         curry:= curry + rand(-200, 200);
  1112.         writestuff(1)
  1113.         end;
  1114.     2:  begin
  1115.         stardate:= stardate + rand(0,100) div 10;
  1116.         writestuff(2)
  1117.         end;
  1118.     3:  begin
  1119.         totalpower:= rand(0,500);
  1120.         shields:= totalpower div 2;
  1121.         writestuff(3)
  1122.         end;
  1123.       4,7:  if syshields < 0 then
  1124.           begin
  1125.           systems[phasers]:= 0;
  1126.           systems[torpedos]:= 0;
  1127.           nmbrtorps:= 0;
  1128.           totalpower:= shields;
  1129.           writestuff(4)
  1130.          end;
  1131.     5:  if syshields < 0 then
  1132.            begin
  1133.            for i:= computer to impulse do systems[i]:= rand(0,systems[i]);
  1134.            writestuff(5)
  1135.            end;
  1136.     6:  begin
  1137.         enemyattack(pass);
  1138.         writestuff(6)
  1139.         end;
  1140.     8:  begin
  1141.         totalpower:= totalpower + 10000;
  1142.         writestuff(8)
  1143.         end;
  1144.     9:  begin
  1145.         stardate:= stardate - rand(0,100) div 10;
  1146.         writestuff(9)
  1147.         end;
  1148.        10:  begin
  1149.         for i:= computer to impulse do systems[i]:= 100;
  1150.         writestuff(10)
  1151.         end
  1152.     end;
  1153.   end; {do question}
  1154.  
  1155. begin
  1156.   { gstat   | meaning                   }
  1157.   { --------+-------------------------- }
  1158.   {  -2     |                           }
  1159.   {  -1     |                           }
  1160.   {   0     | destroyed (shields < 0)   }
  1161.   {   1     | quit                      }
  1162.   {   2     | ran out of time           }
  1163.   {   3     | successful return         }
  1164.   {   4     | collided with something   }
  1165.   {   5     | didn't fulfill mission    }
  1166.   {   6     | player gets 1st move      }
  1167.   {   7     | saved game                }
  1168.   
  1169.   repeat
  1170.     if gstat = 6 then gstat := 3 { called with 3 when enemy gets first move }
  1171.     else                         { called with 6 when player gets first move}
  1172.       begin  { note:  only at inception of playgame from then on gstat = 3 }
  1173.     allshields := allshields - 1;
  1174.     syshields  := syshields - 1;
  1175.     confuse    := confuse - 1;
  1176.     nomove     := nomove - 1;
  1177.     seeall     := seeall - 1;
  1178.     longer     := longer - 1;
  1179.     stardate   := stardate + 0.1;
  1180.     if stardate > deadline then finishup(false);
  1181.     enemyattack(go); (* fire at ship,etc.*)
  1182.     systemchek
  1183.       end;
  1184.     clrmesg;
  1185.     if not out(computer) then updateboard
  1186.     else
  1187.       begin
  1188.     if rand(0,9) = 3 then updateboard;
  1189.     mesg(4, '  Computer unreliable')
  1190.       end;
  1191.     getcommand { and do it }
  1192.   until partdone or alldone;
  1193. 10: end; { playgame}
  1194.  
  1195.